package cn.iocoder.yudao.module.product.util;

import freemarker.template.Configuration;
import freemarker.template.Template;
import org.springframework.stereotype.Component;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * 导出word工具类
 */
@Component
public class WordUtils {

    private static Configuration configuration = null;

    static {
        configuration = new Configuration(Configuration.VERSION_2_3_0);
        configuration.setDefaultEncoding("utf-8");
        configuration.setClassForTemplateLoading(WordUtils.class, "/template");
    }

    /**
     * 导出word
     *
     * @param map          需要填入的字段
     * @param templateName 模板名称
     * @return word字节流
     */
    public static byte[] getDocBytes(Map<?, ?> map, String templateName) {
        File file;
        Template freemarkerTemplate;
        try {
            freemarkerTemplate = configuration.getTemplate(templateName);
            // 调用工具类的createDoc方法生成Word文档
            file = createDoc(map, freemarkerTemplate);
            // 调用XmlDocToDocxUtil工具类的invoke方法将doc转换成docx
            String docxPath = XmlDocToDocxUtil.invoke(file.getAbsolutePath());
            // 读取docx文件
            File docxFile = new File(docxPath);
            // 使用FileUtils工具类的getFileBytes方法读取文件字节流
            byte[] bytes = FileUtils.getFileBytes(docxFile);
            // 删除生成的文件
            FileUtils.deleteFile(file.getAbsolutePath());
            FileUtils.deleteFile(docxFile.getAbsolutePath());
            return bytes;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 创建word文档
     *
     * @param dataMap  需要填入的字段
     * @param template 模板
     * @return 生成的模板文件
     */
    public static File createDoc(Map<?, ?> dataMap, Template template) {
        String name = System.currentTimeMillis() + ".doc";
        File f = new File(name);
        try {
            Writer w = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), StandardCharsets.UTF_8));
            template.process(dataMap, w);
            w.close();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
        return f;
    }

}